package com.yuanmei.datas;

import android.util.Log;

import com.yuanmei.model.TickQuote;
import com.yuanmei.common.Utils;

import java.util.Date;
import java.util.List;
import java.util.concurrent.LinkedBlockingDeque;

public class FetchTickDaemon {
    private static final String TAG = FetchTickDaemon.class.getSimpleName();

    private final LinkedBlockingDeque<FetchInfo> mPendingStocks;
    private final Thread mFetchThread;
    private FetchRealTimeTickListener mFetchListener;
    private boolean mFetchThreadRunning = true;

    public enum EmTickType {
        INDEX_REAL_TIME,
        STOCK_REAL_TIME,
        INDEX_HISTORY,
        STOCK_HISTORY
    }

    private static class FetchInfo {
        private final String mNetEaseCode;
        private final EmTickType mTickType;
        private final Date mTickDate;

        private FetchInfo(String neCode, EmTickType type, Date date) {
            mNetEaseCode = neCode;
            mTickType = type;
            mTickDate = date;
        }
    }

    public interface FetchRealTimeTickListener {
        void onTickFetched(String neCode, EmTickType type, Date date, List<TickQuote> tqs);
    }

    private void fetchTickData(FetchInfo info) {
        String neCode = info.mNetEaseCode;
        EmTickType tickType = info.mTickType;
        Date date = info.mTickDate;

        List<TickQuote> tickQuotes = null;
        switch (tickType) {
            case INDEX_REAL_TIME:
                tickQuotes = NetEaseWebSource.getRealTimeTickData(neCode, date);
                break;
            case STOCK_REAL_TIME:
                tickQuotes = SinaWebSource.getRealTimeTickData(neCode, date);
                break;
            case INDEX_HISTORY:
            case STOCK_HISTORY:
                tickQuotes =
                        Utils.getHistoryTickData(neCode, date);
                break;
        }
        if (mFetchListener != null) {
            mFetchListener.onTickFetched(neCode, tickType, date, tickQuotes);
        }
    }

    private class FetchTickTask implements Runnable {
        @Override
        public void run() {
            while (mFetchThreadRunning) {
                FetchInfo info = null;
                try {
                    info = mPendingStocks.takeFirst();
                    fetchTickData(info);
                } catch (InterruptedException e) {
                    break;
                } catch (Exception e) {
                    Log.e(TAG, "Unknown exception do fetch tick of stock:"
                            + (info == null ? "Null" : "" + info.mNetEaseCode), e);
                }
            }
        }
    }

    private static FetchTickDaemon sFetchDaemonInstanc = null;

    private FetchTickDaemon() {
        mPendingStocks = new LinkedBlockingDeque<>();
        mFetchThread = new Thread(new FetchTickTask(), "BGDown");
        mFetchThread.start();
    }

    public static FetchTickDaemon getInstance() {
        if (sFetchDaemonInstanc == null) {
            sFetchDaemonInstanc = new FetchTickDaemon();
        }
        return sFetchDaemonInstanc;
    }

    public void startPriorFetch(String neCode, EmTickType type, Date date) {
        mPendingStocks.addFirst(new FetchInfo(neCode, type, date));
    }

//    void scheduleNormalUpdate(List<StockItem> updateList) {
//        for (StockItem item : updateList) {
//            mPendingStocks.addLast(
//                    new FetchInfo(item.netEaseCode(),
//                            item.isMarketIndex(),
//                            EmKLineType.DAY_LINE));
//        }
//    }

    public void stop() {
        mFetchThreadRunning = false;
        mFetchThread.interrupt();
    }

    public void registerListener(FetchRealTimeTickListener listener) {
        mFetchListener = listener;
    }

    public void unregisterListener(FetchRealTimeTickListener listener) {
        if (mFetchListener == listener) {
            mFetchListener = null;
        }
    }

}